package cn.shop.merchant.controller.user;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.session.SaSessionCustomUtil;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.shop.merchant.model.user.MerchantPermission;
import cn.shop.merchant.req.IdCardReq;
import cn.shop.merchant.req.MerchantUserQueryReq;
import cn.shop.merchant.req.PhoneCheckReq;
import cn.shop.merchant.req.TransactionPasswordReq;
import cn.shop.merchant.service.BackSettingService;
import cn.shop.merchant.service.FundDetailService;
import cn.shop.merchant.service.MerchantPermissionService;
import cn.shop.merchant.service.MerchantUserService;
import cn.shop.thiredparty.service.ThiredpartyService;
import cn.shop.transcation.backSetting.entity.BackSetting;
import cn.shop.transcation.detail.entity.TransactionRecordQueryReq;
import cn.shop.transcation.merchantRateModule.entity.MerchantRate;
import cn.shop.transcation.merchantUser.mapper.entity.MerchantUser;
import cn.shop.utils.ApiCode;
import cn.shop.utils.ApiResult;
import cn.shop.utils.Putif;
import cn.shop.utils.annotation.OperationLog;
import cn.shop.utils.constant.Regular;
import cn.shop.utils.constant.SMSVerificationCode;
import cn.shop.utils.enums.OperationType;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static cn.shop.utils.constant.Constant.UID;
import static cn.shop.utils.constant.SystemSettingConstant.P_ALI_WITHDRAW_SHARE;
import static cn.shop.utils.constant.SystemSettingConstant.P_BANK_WITHDRAW_SHARE;
import static cn.shop.utils.constant.SystemSettingConstant.U_ALI_WITHDRAW_SUB;
import static cn.shop.utils.constant.SystemSettingConstant.U_BANK_WITHDRAW_SUB;
import static cn.shop.utils.constant.SystemSettingConstant.WITHDRAW_DAY_COUNT;

/**
 * 管理中心
 *
 * @author : 李一涵
 * @date : Created in 2021-11-11 14:44
 * @description :
 */
@SaCheckLogin
@RestController
@RequestMapping("/user")
public class MerchantUserController {

	@Resource
	private MerchantUserService userService;

	@Resource
	private MerchantPermissionService permissionService;

	@Resource
	private ThiredpartyService thiredpartyService;
	@Resource
	private FundDetailService detailService;
	@Resource
	private BackSettingService backSettingService;

	/**
	 * 银行卡验证
	 *
	 * @return 修改结果
	 */
	@PutMapping("setIdCard")
	@OperationLog(desc = "进行实名认证", type = OperationType.UPDATE)
	public ApiResult<Map<String, Object>> setIdCard(@RequestBody IdCardReq idCardReq) {
		return userService.setIdCard(idCardReq);
	}

	/**
	 * 手机号验证
	 *
	 * @return 修改结果
	 */
	@PutMapping("setPhone")
	@OperationLog(desc = "设置手机号", type = OperationType.UPDATE)
	public ApiResult<Map<String, Object>> setPhone(@RequestBody PhoneCheckReq phoneCheckReq) {
		return ApiResult.result(userService.setPhone(phoneCheckReq));
	}

	/**
	 * 设置交易密码的短信验证码
	 *
	 * @return 修改结果
	 */
	@GetMapping("getPhoneCode")
	public ApiResult<Map<String, Object>> getPhoneCode(@RequestParam String phone) {
		String code = RandomUtil.randomNumbers(6);
		SaSession session = SaSessionCustomUtil.getSessionById(SMSVerificationCode.PHONE_PASSWORD_KEY + phone);
		session.set("code", code);
		session.updateTimeout(300);
		thiredpartyService.sendSms(code, 5, phone);
		return ApiResult.success("验证码发送成功!");
	}

	/**
	 * 设置交易密码
	 *
	 * @return 修改结果
	 */
	@PutMapping("setTransactionPassword")
	@OperationLog(desc = "设置交易密码", type = OperationType.UPDATE)
	public ApiResult<Map<String, Object>> setTransactionPassword(@RequestBody TransactionPasswordReq transactionPasswordReq) {
		return ApiResult.result(userService.setTransactionPassword(transactionPasswordReq));
	}

	/**
	 * 设置交易密码的短信验证码
	 *
	 * @return 修改结果
	 */
	@GetMapping("getTPCode")
	public ApiResult<Map<String, Object>> getTransactionPasswordCode(@RequestParam String phone) {
		String code = RandomUtil.randomNumbers(6);
		SaSession session = SaSessionCustomUtil.getSessionById(SMSVerificationCode.TRANSACTION_PASSWORD_KEY + phone);
		session.set("code", code);
		session.updateTimeout(300);
		thiredpartyService.sendSms(code, 5, phone);
		return ApiResult.success("验证码发送成功!");
	}

	/**
	 * 新增管理员
	 *
	 * @param user 管理员信息
	 * @return 返回结果
	 */
	@PostMapping("insert")
	@OperationLog(desc = "新增管理员", type = OperationType.CREATE)
	public ApiResult<Map<String, Object>> insert(@RequestBody MerchantUser user) {
		if (userService.hasAccount(user.getAccount())) {
			return ApiResult.fail("当前账户已存在");
		}
		if (StrUtil.isBlank(user.getPassword())) {
			return ApiResult.fail("密码不能为空");
		}
		boolean match = ReUtil.isMatch(Regular.PASSWORD, user.getPassword());
		if (!match) {
			return ApiResult.fail(ApiCode.PARAMETER_ERROR, Regular.PASSWORD_MASSAGE);
		}
		long uid = StpUtil.getSession().getLong(UID);
		user.setPassword(DigestUtil.bcrypt(user.getPassword()));
		user.setState(2);
		user.setUid(uid);
		boolean isSuccess = userService.save(user);
		return ApiResult.result(isSuccess);
	}

	/**
	 * 更新管理员
	 *
	 * @param user 管理员信息
	 * @return 返回结果
	 */
	@PutMapping("update")
	@OperationLog(desc = "修改管理员", type = OperationType.UPDATE)
	public ApiResult<Map<String, Object>> update(@RequestBody MerchantUser user) {
		long uid = StpUtil.getSession().getLong(UID);
		String password = user.getPassword();
		if (StrUtil.isNotBlank(password)) {
			boolean match = ReUtil.isMatch(Regular.PASSWORD, password);
			if (!match) {
				return ApiResult.fail(ApiCode.PARAMETER_ERROR, Regular.PASSWORD_MASSAGE);
			}
			user.setPassword(DigestUtil.bcrypt(password));
		}
		boolean isSuccess = userService.updateUser(uid, user);
		return ApiResult.result(isSuccess);
	}

	/**
	 * 获取所有权限菜单
	 *
	 * @return 返回结果
	 */
	@GetMapping("/menu/all")
	public ApiResult<List<MerchantPermission>> allMenu() {
		return ApiResult.success(permissionService.allPermissionTree());
	}

	/**
	 * 获取管理员列表
	 *
	 * @param req 查询条件
	 * @return 返回结果
	 */
	@GetMapping("/list")
	public ApiResult<Map<String, Object>> list(MerchantUserQueryReq req) {
		long uid = StpUtil.getSession().getLong(UID);
		long loginId = StpUtil.getLoginIdAsLong();
		Map<String, Object> data = userService.listUser(uid, loginId, req);
		return ApiResult.success(data);
	}

	/**
	 * 变更管理员状态
	 *
	 * @param ids    编号，多个按逗号分割
	 * @param status 状态
	 * @return 返回结果
	 */
	@PutMapping("/change/status/{ids}")
	@OperationLog(desc = "变更管理员状态", type = OperationType.UPDATE)
	public ApiResult<Map<String, Object>> changeStatus(@PathVariable("ids") long[] ids, Integer status) {
		long uid = StpUtil.getSession().getLong(UID);
		boolean isSuccess = userService.changeStatus(ids, uid, status);
		return ApiResult.result(isSuccess);
	}

	/**
	 * 删除管理员
	 *
	 * @param ids 编号，多个按逗号分割
	 * @return 返回结果
	 */
	@DeleteMapping("/delete/{ids}")
	@OperationLog(desc = "删除管理员", type = OperationType.DELETE)
	public ApiResult<Map<String, Object>> delete(@PathVariable("ids") long[] ids) {
		long uid = StpUtil.getSession().getLong(UID);
		boolean isSuccess = userService.deleteUser(ids, uid);
		return ApiResult.result(isSuccess);
	}

	/**
	 * 获取管理员信息
	 *
	 * @param id 编号
	 * @return 返回结果
	 */
	@GetMapping("/info/{id}")
	public ApiResult<Map<String, Object>> info(@PathVariable("id") long id) {
		long uid = StpUtil.getSession().getLong(UID);
		Map<String, Object> data = userService.getUser(id, uid);
		return ApiResult.success(data);
	}

	/**
	 * 获取当前登录人信息
	 *
	 * @return 返回结果
	 */
	@GetMapping("/info")
	public ApiResult<Map<String, Object>> info() {
		long uid = StpUtil.getLoginIdAsLong();
		Map<String, Object> data = userService.getUser(uid);
		return ApiResult.success(data);
	}

	/**
	 * 获取当前商户交易统计
	 *
	 * @param req 查询条件
	 * @return 返回结果
	 */
	@GetMapping("/statistics")
	public ApiResult<Map<String, Object>> statistics(TransactionRecordQueryReq req) {
		long uid = StpUtil.getSession().getLong(UID);
		/*if (req.getStartTime() == null && req.getEndTime() == null) {
			LocalDateTime now = LocalDateTime.now();
			req.setStartTime(now.withHour(0).withMinute(0));
			req.setEndTime(now.withHour(23).withMinute(59));
		}*/
		req.setType(1);
		return ApiResult.success(detailService.statistics(uid, req));
	}

	/**
	 * 查看提现费率信息
	 *
	 * @return 返回结果
	 */
	@GetMapping("/rate")
	public ApiResult<Map<String, Object>> rateDetail() {
		List<String> keys = Arrays.asList(P_BANK_WITHDRAW_SHARE, P_ALI_WITHDRAW_SHARE,
				U_ALI_WITHDRAW_SUB, U_BANK_WITHDRAW_SUB, WITHDRAW_DAY_COUNT);
		List<BackSetting> list = backSettingService.list(Wrappers.<BackSetting>lambdaQuery().in(BackSetting::getKey, keys));
		Map<String, Object> map = new HashMap<>();
		list.forEach(setting -> map.put(setting.getKey(), setting.getValue()));
		return ApiResult.success(map);
	}

	/**
	 * 修改客服信息
	 *
	 * @param user 客服信息（传空位清除）
	 * @return
	 */
	@PutMapping("/service")
	public ApiResult<Map<String, Object>> service(@RequestBody MerchantUser user) {
		long uid = StpUtil.getSession().getLong(UID);
		return ApiResult.result(userService.update(Wrappers.<MerchantUser>lambdaUpdate()
				.set(MerchantUser::getService, user.getService())
				.eq(MerchantUser::getId, uid)));
	}

	/**
	 * 获取客服信息
	 *
	 * @return
	 */
	@GetMapping("/service")
	public ApiResult<Map<String, Object>> service() {
		long uid = StpUtil.getSession().getLong(UID);
		MerchantUser user = userService.getById(uid);
		return ApiResult.success(Putif.start().anyway("service", user.getService()).get());
	}

	/**
	 * 获取收益设置
	 *
	 * @return
	 */
	@GetMapping("/charge")
	public ApiResult<Map<String, Object>> rate() {
		long uid = StpUtil.getSession().getLong(UID);
		MerchantRate rate = userService.getRate(uid);
		if (rate != null) {
			return ApiResult.success(Putif.start()
					.anyway("chargeSingle", rate.getChargeSingle())
					.anyway("chargeRate", rate.getChargeRate())
					.anyway("singleType", rate.getSingleType())
					.anyway("rateType", rate.getRateType())
					.anyway("templateFloat", rate.getTemplateFloat())
					.anyway("singleAdditional", rate.getSingleAdditional())
					.anyway("rateAdditional", rate.getRateAdditional())
					.get());
		}
		return ApiResult.success(Putif.start().get());
	}

	/**
	 * 更新收益设置
	 *
	 * @return
	 */
	@PutMapping("/charge")
	public ApiResult<Map<String, Object>> updateRate(@RequestBody MerchantRate rate) {
		long uid = StpUtil.getSession().getLong(UID);
		return ApiResult.result(userService.updateRate(uid, rate));
	}
}
